
#ifndef __H_SYMPHONY_CREATURE
#define __H_SYMPHONY_CREATURE

#include <list>
#include <vector>
#include "estring.h"
#include "keywords.h"

// Status...
#define INACTIVE      0
#define CONNECTING    1
#define CONNECTED     2
#define DISCONNECTED  3

// Types...
#define TYPE_AVATAR   A
#define TYPE_MOB      B

// Levels...
#define LEVEL_HERO  100
#define LEVEL_NEWB  10
#define HERO        LEVEL_HERO
#define NEWBIE      LEVEL_NEWB
#define LORD        (HERO+2)
#define DUKE        (HERO+5)
#define KING        (HERO+10)
#define IMMORTAL    (HERO+15)
#define BUILDER     (HERO+16)
#define DEMIGOD     (HERO+17)
#define GOD         (HERO+21)
#define CREATOR     (HERO+25)

// Gender...
#define MALE    0
#define FEMALE  1
#define NEUTRAL 2

// Modes...
#define MODE_NONE     0
#define MODE_AEDIT    1
#define MODE_MEDIT    2
#define MODE_OEDIT    3
#define MODE_PEDIT    4
#define MODE_REDIT    5

class Area;
class Handler;
class Object;
class Room;
class Mob;



class Creature: public Keywords {
  private:
    std::vector<Handler*>       _handlers;
    unsigned long               _ID;
    std::string                 _name;
    std::string                 _brief;
    std::string                 _description;
    unsigned short              _level;
    unsigned long               _type;
    Room*                       _room;
    unsigned short              _gender;
    unsigned short              _mode;
    void*                       _pointer;
    emap                        _values;
    std::list<Object*>          _objects;

  public:
    // Constructors...
    Creature( void );
    Creature( const Creature& ref );
    virtual ~Creature( void );

    // Public accessor methods...
    std::vector<Handler*>&      handlers( void )                                                  { return _handlers; }
    void                        ID( const unsigned long& ID )                                     { _ID = ID; }
    unsigned long               ID( void ) const                                                  { return _ID; }
    void                        name( const std::string& name )                                   { _name = name; }
    std::string                 name( void ) const                                                { return _name; }
    void                        brief( const std::string& brief )                                 { _brief = brief; }
    std::string                 brief( void ) const                                               { return _brief; }
    void                        description( const std::string& description )                     { _description = description; }
    std::string                 description( void ) const                                         { return _description; }
    std::string*                descriptionp( void )                                              { return &_description; } // this needs to be exposed for the text editor
    void                        level( const unsigned short& level )                              { _level = level; }
    unsigned short              level( void ) const                                               { return _level; }
    void                        typeFlags( const unsigned long& type )                            { _type = type; }
    unsigned long               typeFlags( void ) const                                           { return _type; }
    void                        type( const unsigned long& type, bool value )                     { typeFlags( value ? (typeFlags()|type) : (typeFlags()&(~type)) ); }
    bool                        type( const unsigned long& type )                                 { return ( (typeFlags()&type) == type ); }
    void                        room( Room* room );
    Room*                       room( void )                                                      { return _room; }
    void                        gender( const unsigned short& gender )                            { _gender = gender; }
    unsigned short              gender( void ) const                                              { return _gender; }
    const char*                 genderName( void ) const;
    void                        mode( const unsigned short& mode )                                { _mode = mode; }
    unsigned short              mode( void ) const                                                { return _mode; }
    void                        pointer( void* pointer )                                          { _pointer = pointer; }
    void*                       pointer( void )                                                   { return _pointer; }
    emap&                       values( void )                                                    { return _values; }
    const emap&                 values( void ) const                                              { return _values; }
    std::list<Object*>&         objects( void )                                                   { return _objects; }
    const std::list<Object*>&   objects( void ) const                                             { return _objects; }

    // Public methods...
    unsigned short              canSee( Creature* target );
    std::string                 seeName( Creature* target, bool capitalize = false );
    unsigned short              canSee( Object* target );
    std::string                 seeName( Object* target, bool capitalize = false );
    bool                        canAlter( Creature* target );
    /* canMove() asseses the potential to move in the given direction.  If the move is
     * not possible, then message is filled with the reason why */
    bool                        canMove( const unsigned short& direction, std::string& message );
    /* move() will move the creature in the given direction, and send the appropriate
     * messages to both the creature, and the room left/entered. */
    void                        move( const unsigned short& direction );
    Handler*                    handler( void );
    void                        pushHandler( Handler* handler );
    void                        popHandler( void );
    void                        replaceHandler( Handler* handler );
    void                        handle( void );
    void                        add( Object* object );
    void                        remove( Object* object );
    Object*                     findObject( const std::string& name, unsigned scope = SEARCH_ROOM );
    Creature*                   findCreature( const std::string& name, unsigned scope = SEARCH_ROOM );

    // Pure virtual public methods...
    virtual bool                save( void )                                                      = 0;
    virtual bool                load( void )                                                      { return false; }
    virtual bool                destroy( void )                                                   = 0;

    // Virtual public methods...
    void                        status( const unsigned short& status )                            { }
    unsigned short              status( void )                                                    { return INACTIVE; }
    virtual void                send( const std::string& message )                                { }
    virtual void                send( const char* format, ... )                                   { }
    virtual void                disconnected( const bool& disconnected )                          { }
    virtual bool                disconnected( void )                                              { return false; }
    virtual bool                checkPassword( const std::string& password )                      { return false; }
    virtual void                adminFlags( const unsigned long& adminFlags )                     { }
    virtual unsigned long       adminFlags( void ) const                                          { return false; }
    virtual void                admin( const unsigned long& flag, const bool& value )             { }
    virtual bool                admin( const unsigned long& flag ) const                          { return false; }
    virtual void                gechoColor( const char& gechoColor )                              { }
    virtual char                gechoColor( void ) const                                          { return 'x'; }
    virtual void                replyTo( const std::string& replyTo )                             { }
    virtual std::string         replyTo( void )                                                   { return std::string(); }
    virtual void                channelFlags( const unsigned long& channelFlags )                 { }
    virtual unsigned long       channelFlags( void ) const                                        { return 0; }
    virtual void                channel( const unsigned long& flag, const bool& value )           { }
    virtual bool                channel( const unsigned long& flag ) const                        { return 0; }
    virtual void                pedit( Creature* pedit )                                          { }
    virtual Creature*           pedit( void )                                                     { return NULL; }
    virtual void                aedit( Area* aedit )                                              { }
    virtual Area*               aedit( void )                                                     { return NULL; }
    virtual void                oedit( Object* object )                                           { }
    virtual Object*             oedit( void )                                                     { return NULL; }
    virtual void                medit( Mob* mob )                                                 { }
    virtual Mob*                medit( void )                                                     { return NULL; }
    virtual void                poofin( const std::string& poofin )                               { }
    virtual const char*         poofin( void ) const                                              { return ""; }
    virtual void                poofout( const std::string& poofout )                             { }
    virtual const char*         poofout( void ) const                                             { return ""; }

};



#endif // #ifndef __H_SYMPHONY_CREATURE

